﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ReallyReallyReallySimpleRoguelike.Managers;
using ReallyReallyReallySimpleRoguelike.Entities;
using System.Drawing;
using System.Threading;
using ReallyReallyReallySimpleRoguelike.Helpers;

namespace ReallyReallyReallySimpleRoguelike.Screens
{
    class DungeonScreen:Screen
    {

        ReplayScreen replayScreen;
        public QuitScreen QuitScreen;
        GameConclusionScreen concludeGameScreen;
        Player player;
        private bool hasJumped = false;
        private bool hasFired = false;
        bool playerMoved;
        bool processMonsters;
        
        

        public DungeonScreen()
        {
            replayScreen = new ReplayScreen();
            QuitScreen = new QuitScreen();
            concludeGameScreen = new GameConclusionScreen();
        }

        public void DoLogic()
        {
            processMonsters = true;
            playerMoved = true;
            DungeonManager.Instance.Redraw = true;

            ProcessInput();

            //Can later be part of the prop manager perhaps or the fireball itself
            Fireball fireball = DungeonManager.Instance.PropManager.Fireball;
            if (fireball.IsActive)
                ProcessFireball(fireball);

            // does things like auto pick up sword and take stairs
            if (playerMoved)
                CheckNewTile();

            if (processMonsters)
            {
                DungeonManager.Instance.CreatureManager.ProcessMonsters();
            }
        }

        private static void ProcessFireball(Fireball fireball)
        {
            while (DungeonManager.Instance.DungeonLevel.IsOKToMove(fireball.Position))
            {
                //Do fireball stuff
                //DungeonManager.Instance.PropManager.Fireball
                //Fireball move
                DungeonManager.Instance.PropManager.Fireball.Move(fireball.Position, fireball.Direction, 1);
                //Fireball kill monsters
                List<Monster> monstersInBattle = DungeonManager.Instance.CreatureManager.monsters.Where(m => m.X == fireball.X && m.Y == fireball.Y).ToList();
                foreach (Monster m in monstersInBattle)
                {
                    fireball.Kill(m);

                    DungeonManager.Instance.PlaySound(SoundList.Battle);

                    fireball.ImageCharacter = "*";

                    DungeonManager.Instance.DungeonVisualizer.Flash(fireball);

                    fireball.ImageCharacter = "o";
                    fireball.Color = ConsoleColor.Magenta;
                }
                //Draw
                DungeonManager.Instance.ForceRedraw();

            }
            DungeonManager.Instance.PropManager.Fireball.IsActive = false;
            DungeonManager.Instance.Redraw = true;
        }

        public override void Show()
        {
            Console.Clear();
            StartGame();
            MainGameLoop();
        }

        private void StartGame()
        {
            DungeonManager.Instance.Initialize();

            DungeonManager.Instance.ForceRedraw();
            DungeonManager.Instance.DungeonVisualizer.ForceFullVisualization(DungeonManager.Instance.DungeonLevel);

            player = DungeonManager.Instance.CreatureManager.Player;

            hasJumped = false;
            hasFired = false;

            MainGameLoop();
            
            concludeGameScreen.Show(DungeonManager.Instance.PlayerHasWon.Value);

            replayScreen.Show();
        }

        private void MainGameLoop()
        {
            while (DungeonManager.Instance.IsGameActive)
            {
                
                //read input
                HandleInput();

                //do logic
                DoLogic();

                //Draw
                DungeonManager.Instance.DrawDungeon();

            }
        }

        public void HandleInput()
        {
            DungeonManager.Instance.InputManager.ReadKeys();
        }

        private void CheckNewTile()
        {
            Point newPosition = new Point(player.X, player.Y);

            //auto pick up sword
            if (DungeonManager.Instance.DungeonLevel.GetTile(newPosition) is Sword && player.Inventory.Count == 0)
            {
                Sword sword = (Sword)DungeonManager.Instance.DungeonLevel.GetTile(newPosition);
                player.Inventory.Add(sword);
                DungeonManager.Instance.PropManager.RemoveSword(sword);
            }

            // auto take stairwell
            else if (DungeonManager.Instance.DungeonLevel.GetTile(newPosition) is Stairwell)
            {
                //check for victory
                if (DungeonManager.Instance.CurrentDungeonLevel >= 5)
                {
                    DungeonManager.Instance.gameOver = true;
                }
                else
                {
                    MoveToNextLevel();
                }
            }
        }

        private void MoveToNextLevel()
        {
            hasJumped = false;
            hasFired = false;

            //no sword on next level. Murha, ha, ha, ha!!!
            //player.Inventory.Clear();
            //sword now has three uses

            DungeonManager.Instance.CurrentDungeonLevel++;
            DungeonManager.Instance.Dungeon.Levels.Add(new DungeonLevel(DungeonManager.Instance.CurrentDungeonLevel, Constants.DungeonWidth, Constants.DungeonHeight));
            DungeonManager.Instance.DungeonLevel.CreateRandomDungeonObjects();
            processMonsters = false;
        }

        private void ProcessInput()
        {
            ActionManager ActionManager = DungeonManager.Instance.ActionManager;
            Player player = DungeonManager.Instance.CreatureManager.Player;

            //This checks until one is true as we can only have on action press.
            if (ActionManager.IsActionPushed(Actions.North))
                playerMoved = processMonsters = player.MovePlayer(Constants.Direction.N);
            else if (ActionManager.IsActionPushed(Actions.South))
                playerMoved = processMonsters = player.MovePlayer(Constants.Direction.S);
            else if (ActionManager.IsActionPushed(Actions.East))
                playerMoved = processMonsters =player.MovePlayer(Constants.Direction.E);
            else if (ActionManager.IsActionPushed(Actions.West))
                playerMoved = processMonsters = player.MovePlayer(Constants.Direction.W);
            else if (ActionManager.IsActionPushed(Actions.JumpNorth) && !hasJumped)
            {
                playerMoved = processMonsters = player.MovePlayer(Constants.Direction.N, Constants.JumpDistance);
                hasJumped = true;
            }
            else if (ActionManager.IsActionPushed(Actions.JumpSouth) && !hasJumped)
            {
                playerMoved = processMonsters = player.MovePlayer(Constants.Direction.S, Constants.JumpDistance);
                hasJumped = true;

            }
            else if (ActionManager.IsActionPushed(Actions.JumpEast) && !hasJumped)
            {
                playerMoved = processMonsters = player.MovePlayer(Constants.Direction.E, Constants.JumpDistance);
                hasJumped = true;
            }
            else if (ActionManager.IsActionPushed(Actions.JumpWest) && !hasJumped)
            {
                playerMoved = processMonsters = player.MovePlayer(Constants.Direction.W, Constants.JumpDistance);
                hasJumped = true;
            }
            else if (ActionManager.IsActionPushed(Actions.ShootNorth) && !hasFired)
            {
                Constants.Direction d = Constants.Direction.N;
                ShootFireball(d);
            }
            else if (ActionManager.IsActionPushed(Actions.ShootSouth) && !hasFired)
            {
                Constants.Direction d = Constants.Direction.S;
                ShootFireball(d);
            }
            else if (ActionManager.IsActionPushed(Actions.ShootEast) && !hasFired)
            {
                Constants.Direction d = Constants.Direction.E;
                ShootFireball(d);
            }
            else if (ActionManager.IsActionPushed(Actions.ShootWest) && !hasFired)
            {
                Constants.Direction d = Constants.Direction.W;
                ShootFireball(d);
            }
            else if (ActionManager.IsActionPushed(Actions.Wait))
            {
                playerMoved = false;
            }
            else if (ActionManager.IsActionPushed(Actions.Quit))
            {
                GameManager.Instance.dungeonScreen.QuitScreen.Show();
                DungeonManager.Instance.DungeonVisualizer.ForceFullVisualization(DungeonManager.Instance.DungeonLevel);

                processMonsters =playerMoved = false;
            }
            else if (ActionManager.IsActionPushed(Actions.Help))
            {
                HelpScreen hs = new HelpScreen();
                hs.Show();
                DungeonManager.Instance.DungeonVisualizer.ForceFullVisualization(DungeonManager.Instance.DungeonLevel);
                processMonsters = playerMoved = false;
            }
            else if (ActionManager.IsActionPushed(Actions.SoundToggle))
            {
                //Toggle sound
                if (Properties.Settings.Default.SoundToggle)
                    Properties.Settings.Default.SoundToggle = false;
                else
                    Properties.Settings.Default.SoundToggle = true;

                Properties.Settings.Default.Save();

                processMonsters = playerMoved =false;
                
            }
            else
            {
                processMonsters = playerMoved = DungeonManager.Instance.Redraw = false;
            }
        }

        private void ShootFireball(Constants.Direction d)
        {
            DungeonManager.Instance.PropManager.Fireball = new Fireball(player.Position, d);
            DungeonManager.Instance.PropManager.Fireball.IsActive = true;
            hasFired = true;
        }

    }
}
